#include "sqlhighlighter.h"
#include <QTextDocument>
#include <QTextCharFormat>
#include <QBrush>
#include <QFont>

SqlHighlighter::SqlHighlighter(QTextDocument *parent)
    : QSyntaxHighlighter(parent)
{
    HighlightingRule rule;

    // 关键字格式（蓝色粗体）
    keywordFormat.setForeground(Qt::darkBlue);
    keywordFormat.setFontWeight(QFont::Bold);
    
    QStringList keywordPatterns = {
        QStringLiteral("\\bSELECT\\b"), QStringLiteral("\\bFROM\\b"), QStringLiteral("\\bWHERE\\b"),
        QStringLiteral("\\bINSERT\\b"), QStringLiteral("\\bUPDATE\\b"), QStringLiteral("\\bDELETE\\b"),
        QStringLiteral("\\bCREATE\\b"), QStringLiteral("\\bDROP\\b"), QStringLiteral("\\bALTER\\b"),
        QStringLiteral("\\bTABLE\\b"), QStringLiteral("\\bINDEX\\b"), QStringLiteral("\\bVIEW\\b"),
        QStringLiteral("\\bTRIGGER\\b"), QStringLiteral("\\bPROCEDURE\\b"), QStringLiteral("\\bFUNCTION\\b"),
        QStringLiteral("\\bDATABASE\\b"), QStringLiteral("\\bSCHEMA\\b"), QStringLiteral("\\bPRIMARY\\b"),
        QStringLiteral("\\bKEY\\b"), QStringLiteral("\\bFOREIGN\\b"), QStringLiteral("\\bREFERENCES\\b"),
        QStringLiteral("\\bCONSTRAINT\\b"), QStringLiteral("\\bUNIQUE\\b"), QStringLiteral("\\bCHECK\\b"),
        QStringLiteral("\\bDEFAULT\\b"), QStringLiteral("\\bNOT\\b"), QStringLiteral("\\bNULL\\b"),
        QStringLiteral("\\bAND\\b"), QStringLiteral("\\bOR\\b"), QStringLiteral("\\bIN\\b"),
        QStringLiteral("\\bEXISTS\\b"), QStringLiteral("\\bBETWEEN\\b"), QStringLiteral("\\bLIKE\\b"),
        QStringLiteral("\\bAS\\b"), QStringLiteral("\\bON\\b"), QStringLiteral("\\bJOIN\\b"),
        QStringLiteral("\\bINNER\\b"), QStringLiteral("\\bLEFT\\b"), QStringLiteral("\\bRIGHT\\b"),
        QStringLiteral("\\bOUTER\\b"), QStringLiteral("\\bCROSS\\b"), QStringLiteral("\\bFULL\\b"),
        QStringLiteral("\\bUNION\\b"), QStringLiteral("\\bALL\\b"), QStringLiteral("\\bDISTINCT\\b"),
        QStringLiteral("\\bGROUP\\b"), QStringLiteral("\\bBY\\b"), QStringLiteral("\\bORDER\\b"),
        QStringLiteral("\\bHAVING\\b"), QStringLiteral("\\bLIMIT\\b"), QStringLiteral("\\bOFFSET\\b"),
        QStringLiteral("\\bINTO\\b"), QStringLiteral("\\bVALUES\\b"), QStringLiteral("\\bSET\\b"),
        QStringLiteral("\\bADD\\b"), QStringLiteral("\\bCOLUMN\\b"), QStringLiteral("\\bTO\\b"),
        QStringLiteral("\\bIF\\b"), QStringLiteral("\\bELSE\\b"), QStringLiteral("\\bBEGIN\\b"),
        QStringLiteral("\\bEND\\b"), QStringLiteral("\\bWHEN\\b"), QStringLiteral("\\bTHEN\\b"),
        QStringLiteral("\\bCASE\\b"), QStringLiteral("\\bWITH\\b"), QStringLiteral("\\bRECURSIVE\\b"),
        QStringLiteral("\\bOVER\\b"), QStringLiteral("\\bPARTITION\\b"), QStringLiteral("\\bROW\\b"),
        QStringLiteral("\\bROWS\\b"), QStringLiteral("\\bRANGE\\b"), QStringLiteral("\\bPRECEDING\\b"),
        QStringLiteral("\\bFOLLOWING\\b"), QStringLiteral("\\bCURRENT\\b"), QStringLiteral("\\bFOR\\b"),
        QStringLiteral("\\bONLY\\b"), QStringLiteral("\\bUSING\\b"), QStringLiteral("\\bRETURNING\\b"),
        QStringLiteral("\\bCASCADE\\b"), QStringLiteral("\\bRESTRICT\\b"), QStringLiteral("\\bTRUE\\b"),
        QStringLiteral("\\bFALSE\\b")
    };

    for (const QString &pattern : keywordPatterns) {
        rule.pattern = QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption);
        rule.format = keywordFormat;
        highlightingRules.append(rule);
    }

    // 函数格式（洋红色）
    functionFormat.setForeground(Qt::magenta);
    functionFormat.setFontWeight(QFont::Bold);
    
    QStringList functionPatterns = {
        QStringLiteral("\\bCOUNT\\b"), QStringLiteral("\\bSUM\\b"), QStringLiteral("\\bAVG\\b"),
        QStringLiteral("\\bMIN\\b"), QStringLiteral("\\bMAX\\b"), QStringLiteral("\\bABS\\b"),
        QStringLiteral("\\bROUND\\b"), QStringLiteral("\\bCEIL\\b"), QStringLiteral("\\bFLOOR\\b"),
        QStringLiteral("\\bPOWER\\b"), QStringLiteral("\\bSQRT\\b"), QStringLiteral("\\bMOD\\b"),
        QStringLiteral("\\bCOALESCE\\b"), QStringLiteral("\\bNULLIF\\b"), QStringLiteral("\\bCAST\\b"),
        QStringLiteral("\\bCONVERT\\b"), QStringLiteral("\\bSUBSTRING\\b"), QStringLiteral("\\bCONCAT\\b"),
        QStringLiteral("\\bLENGTH\\b"), QStringLiteral("\\bUPPER\\b"), QStringLiteral("\\bLOWER\\b"),
        QStringLiteral("\\bTRIM\\b"), QStringLiteral("\\bLTRIM\\b"), QStringLiteral("\\bRTRIM\\b"),
        QStringLiteral("\\bREPLACE\\b"), QStringLiteral("\\bDATE\\b"), QStringLiteral("\\bTIME\\b"),
        QStringLiteral("\\bYEAR\\b"), QStringLiteral("\\bMONTH\\b"), QStringLiteral("\\bDAY\\b"),
        QStringLiteral("\\bHOUR\\b"), QStringLiteral("\\bMINUTE\\b"), QStringLiteral("\\bSECOND\\b"),
        QStringLiteral("\\bNOW\\b"), QStringLiteral("\\bCURDATE\\b"), QStringLiteral("\\bCURTIME\\b"),
        QStringLiteral("\\bDATEDIFF\\b"), QStringLiteral("\\bDATEADD\\b"), QStringLiteral("\\bEXTRACT\\b"),
        QStringLiteral("\\bPOSITION\\b"), QStringLiteral("\\bCHAR_LENGTH\\b"), QStringLiteral("\\bOCTET_LENGTH\\b"),
        QStringLiteral("\\bCURRENT_DATE\\b"), QStringLiteral("\\bCURRENT_TIME\\b"), QStringLiteral("\\bCURRENT_TIMESTAMP\\b")
    };

    for (const QString &pattern : functionPatterns) {
        rule.pattern = QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption);
        rule.format = functionFormat;
        highlightingRules.append(rule);
    }

    // 单行注释格式（绿色斜体）
    singleLineCommentFormat.setForeground(Qt::darkGreen);
    singleLineCommentFormat.setFontItalic(true);
    rule.pattern = QRegularExpression(QStringLiteral("--[^\n]*"));
    rule.format = singleLineCommentFormat;
    highlightingRules.append(rule);

    // 多行注释格式（绿色斜体）
    multiLineCommentFormat.setForeground(Qt::darkGreen);
    multiLineCommentFormat.setFontItalic(true);

    // 引号格式（红色）
    quotationFormat.setForeground(Qt::red);
    rule.pattern = QRegularExpression(QStringLiteral("\".*\""));
    rule.format = quotationFormat;
    highlightingRules.append(rule);

    rule.pattern = QRegularExpression(QStringLiteral("'.*'"));
    rule.format = quotationFormat;
    highlightingRules.append(rule);

    // 数字格式（深红色粗体）
    numberFormat.setForeground(Qt::darkRed);
    numberFormat.setFontWeight(QFont::Bold);
    rule.pattern = QRegularExpression(QStringLiteral("\\b[0-9]+\\b"));
    rule.format = numberFormat;
    highlightingRules.append(rule);

    // 占位符格式（浅灰色斜体）
    placeholderFormat.setForeground(Qt::gray);
    placeholderFormat.setFontItalic(true);
    rule.pattern = QRegularExpression(QStringLiteral("\\b[A-Za-z_][A-Za-z0-9_]*\\b"));
    rule.format = placeholderFormat;
    highlightingRules.append(rule);

    // 多行注释的开始和结束表达式
    commentStartExpression = QRegularExpression(QStringLiteral("/\\*"));
    commentEndExpression = QRegularExpression(QStringLiteral("\\*/"));
}

void SqlHighlighter::highlightBlock(const QString &text)
{
    // 应用高亮规则
    for (const HighlightingRule &rule : highlightingRules) {
        QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
        while (matchIterator.hasNext()) {
            QRegularExpressionMatch match = matchIterator.next();
            setFormat(match.capturedStart(), match.capturedLength(), rule.format);
        }
    }

    // 处理多行注释
    setCurrentBlockState(0);

    int startIndex = 0;
    if (previousBlockState() != 1)
        startIndex = text.indexOf(commentStartExpression);

    while (startIndex >= 0) {
        QRegularExpressionMatch match = commentEndExpression.match(text, startIndex);
        int endIndex = match.capturedStart();
        int commentLength = 0;

        if (endIndex == -1) {
            setCurrentBlockState(1);
            commentLength = text.length() - startIndex;
        } else {
            commentLength = endIndex - startIndex
                            + match.capturedLength();
        }

        setFormat(startIndex, commentLength, multiLineCommentFormat);
        startIndex = text.indexOf(commentStartExpression, startIndex + commentLength);
    }
}